home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / stut_src / objects.c < prev    next >
C/C++ Source or Header  |  1996-05-27  |  59KB  |  2,452 lines

  1. /*
  2.  * objects.c
  3.  *
  4.  * Purpose:
  5.  * --------
  6.  * Routines de traitement des objets/arbres AES
  7.  *
  8.  * History:
  9.  * --------
  10.  * 1993: fplanque: Created
  11.  */
  12.  
  13.  
  14.      #include "!OPTIONS.H"                /* Options de compilation */         
  15.     #define    THIS_FILE    "OBJECTS.C v1.05 - 03.95"
  16.           
  17.  
  18. /*
  19.  * System headers:
  20.  */
  21.     #include    <stdio.h>
  22.     #include    <string.h>                    /* strlen() etc.. */
  23.     #include    <stdlib.h>                    
  24.     #include    <aes.h>                        /* header AES */
  25.    
  26.  
  27. /*
  28.  * Custom headers:
  29.  */
  30.     #include "SPEC_PU.H"
  31.     #include "S_MALLOC.H"
  32.     #include "STUT_ONE.RSC\STUT_3.H"        /* noms des objets ds le ressource */
  33.     #include    "TEXT_PU.H"                /* Params texte VDI */
  34.     #include    "DTDIR_PU.H"    
  35.     #include    "DATPG_PU.H"    
  36.     #include    "DESK_PU.H"            /* Stockage des ic“nes manipul‚es */
  37.     #include "COLORDEF.H"                /* Couleurs … utiliser */
  38.     #include "AESDEF.H"
  39.     #include    "DEBUG_PU.H"    
  40.     #include    "OBJCT_PU.H"    
  41.     #include    "MAIN_PU.H"    
  42.     #include "VDI_PU.H"
  43.     #include    "WIN_PU.H"    
  44.     #include    "WINDR_PU.H"    
  45.  
  46. /*
  47.  * ------------------------ VARIABLES -------------------------
  48.  */
  49.     
  50. /*
  51.  * External variables: 
  52.  */
  53.     /* 
  54.      * VDI: 
  55.      */
  56.     extern    int        G_ws_handle;            /* handle virtual workstation VDI */
  57.     extern    int         G_pxyarray[18];        /* Liste de coord X,Y pour le VDI */
  58.     extern    MFDB        G_plogMFDB;                /* block ‚cran logique */
  59.     extern    int        G_nb_bitplanes;        /* Nbre de plans graphiques */
  60.     extern    int        G_nb_colors;            /* Nbre de couleurs simultan‚es */
  61.     extern    VDI_TEXT_PARAMS    G_std_text;    /* ParamŠtres du texte standard */    
  62.     /* 
  63.      * Tampon AES: 
  64.      */
  65.     extern    char        *G_tampon_aes;            /* Adr tampon */
  66.     extern    size_t    G_long_tampon;            /* Longueur de ce tampn */
  67.     extern    MFDB        G_tamponMFDB;                /* MFDB pour le tampon AES */
  68.     /* 
  69.      * Config: 
  70.      */
  71.     extern    int        G_cnf_cope_with_ltf;    /* Contourner les bugs de Let'em Fly */
  72.  
  73.  
  74. /*
  75.  * Public variables: 
  76.  */
  77.     /* 
  78.      * Buffer AES: 
  79.      */
  80.     int        G_stock_tampon;                    /* Nre de lignes stock‚es dans le tamp AES */
  81.     char    *    G_tampon_supp;                    /* Tampon suppl‚mentaire */
  82.  
  83.     
  84. /*
  85.  * Private variables: 
  86.  */
  87.     /* 
  88.      * Objets: 
  89.      */
  90.     static    OBJECT    M_single_box=                        /* Boite pŠre d'un directory */
  91.                 {-1, -1, -1, G_BOX, NONE, NORMAL, 0xFF1112L, 0,0, 10000, 10000};
  92.     static    OBJECT    M_icone=                            /* Ic“ne */
  93.                 {-1, -1, -1, G_ICON, SELECTABLE | OUVRABLE, NORMAL, 0L, 0,0, 10, 3};
  94.     static    ICONBLK    M_iconblk =
  95.                 {(int*)2L, (int*)3L, NULL, 4096,0,0, 24,34-28,32,28, 4,36,72,8}; 
  96.     /* 
  97.      * Gestion des formulaires: 
  98.      */
  99.     /* Niveau de r‚cursion dans l'ouverture de formulaires: */
  100.     static    M_form_recurse_depth = 0;        /* Au d‚but: aucun formulaire ouvert */
  101.     /* 
  102.      * Maptree: 
  103.      */
  104.     static    int    M_enable_menu;                /* Faut il faire un enbale ou disable du menu */
  105.      
  106.  
  107. /*
  108.  * ------------------------ FUNCTIONS -------------------------
  109.  */
  110.  
  111. /*
  112.  * init_objects(-)
  113.  *
  114.  * Purpose:
  115.  * --------
  116.  * Init des objets en RAM
  117.  *
  118.  * History:
  119.  * --------
  120.  * fplanque: Created
  121.  */
  122. void init_objects( void )
  123. {
  124.     TRACE0( "Initializing " THIS_FILE );
  125.  
  126.     /*
  127.      * Fixe taille de l'ic“ne g‚n‚rique: 
  128.      */
  129.     M_icone .ob_width  = G_icon_w;
  130.     M_icone .ob_height = G_icon_h;
  131.  
  132.     /*
  133.      * Donne des valeurs par d‚faut … l'iconblk:
  134.      * Ces valeurs sont reprises sur le desktop et tiennent compte de la r‚solution:
  135.      */
  136.     M_iconblk = *(G_desktop_adr[ DSTTERM ] .ob_spec.iconblk);
  137.  
  138.     /*
  139.      * Couleur pŠre de directory: 
  140.      */
  141.     if( G_nb_colors >= 16 )
  142.     {
  143.         M_single_box .ob_spec.obspec .fillpattern = DIR_PATTERN_16;
  144.         M_single_box .ob_spec.obspec .interiorcol = DIR_COLOR_16;
  145.     }
  146.     else if( G_nb_colors >= 4 )
  147.     {
  148.         M_single_box .ob_spec.obspec .fillpattern = DIR_PATTERN_4;
  149.     }
  150. }
  151.  
  152.  
  153.  
  154. /*
  155.  * rsrc_color(-)
  156.  *
  157.  * Purpose:
  158.  * --------
  159.  * Corrige la taille de certains objets
  160.  * Peint les boites de dialogue en couleur quand c'est esth‚tiquement possible (!)
  161.  *
  162.  * History:
  163.  * --------
  164.  * fplanque: Created
  165.  * 29.08.94: parxourt l'arbe mˆme en mono, en effet on ne s'occupe plus seulement de la couleur
  166.  */
  167. void rsrc_color( OBJECT *tree )
  168. {
  169.     maptree( tree, ROOT, NIL, objc_color );
  170. }
  171.  
  172.  
  173.  
  174. /*
  175.  * objc_color(-)
  176.  *
  177.  * Purpose:
  178.  * --------
  179.  * Fixe la couleur et autres attributs 
  180.  * d'un objet
  181.  *
  182.  * History:
  183.  * --------
  184.  * 1993: fplanque: Created
  185.  * 29.08.94: fplanque: Gestion des GROUPTITLEs
  186.  * 02.10.94: gestion des RESIZE_OBJECT
  187.  * 02.02.95: gestion ic“nes moyenne r‚solution
  188.  * 28.03.95: ajout traitement des userdefs bouton croix
  189.  */
  190. int    objc_color( 
  191.             OBJECT *    tree, 
  192.             int        objc )
  193. {
  194.     ICONBLK * pIconBlk;
  195.     int    ob_height;
  196.     int    ob_type     = tree[ objc ] .ob_type;    /* Type de l'objet */
  197.     int    real_type = ob_type & 0x00FF;
  198.     int    ob_flags = tree[ objc ] .ob_flags;    /* Flags de l'objet */
  199.     int    ob_state = tree[ objc ] .ob_state;    /* State de l'objet */
  200.  
  201.     if( ob_state & RESIZE_OBJECT /* = BOUTON_CROIX */ )
  202.     {    /*
  203.          * D‚termine le type d'objet pour savoir quel traitement
  204.          * il faut effectuer:
  205.          */
  206.         switch( real_type )
  207.         {
  208.             case    G_BOX:
  209.                 /*
  210.                  * Il faut mettre en userdef BOUTON_CROIX:
  211.                  */
  212.                 tree[ objc ].ob_spec.userblk = &G_bcroix_ublk;
  213.                 tree[ objc ].ob_type = G_USERDEF ;
  214.                 break;
  215.  
  216.             case    G_TEXT:
  217.             case    G_BOXTEXT:
  218.                 /*
  219.                  * S'il s'agit d'un titre de groupe:
  220.                  * on va diminuer la hauteur de l'objet:
  221.                    */
  222.                   tree[ objc ] .ob_y += 4;
  223.                 tree[ objc ] .ob_height -= 8;
  224.                 break;
  225.  
  226.             case    G_IMAGE:
  227.                 /*
  228.                  * S'il s'agit d'un objet image a qui on veut donner
  229.                  * exactement la largeur du bitmap:
  230.                  */
  231.                 tree[ objc ] .ob_height = tree[ objc ] .ob_spec.bitblk -> bi_hl;
  232.                 break;
  233.                  
  234.             case    G_ICON:
  235.                 /*
  236.                  * S'il s'agit d'une ic“ne:
  237.                  * On augmente la taille verticale … l'equiv de 3 caractŠres
  238.                  */ 
  239.                 ob_height = G_std_text .cell_h * 3;
  240.                 tree[ objc ] .ob_height = ob_height;
  241.                 
  242.                 /*
  243.                  * Modifie positions du texte et de l'icone dans l'objet
  244.                  */
  245.                 pIconBlk = tree[ objc ] .ob_spec.iconblk;
  246.     
  247.                 #if ACCEPT_SMALLFONTS
  248.                     if( G_cell_size_prop == 1 )
  249.                     {    /*
  250.                          * Moyenne r‚solution
  251.                          */
  252.                         pIconBlk -> ib_ytext = ob_height - 8;
  253.                         pIconBlk -> ib_yicon = ob_height - 8 - pIconBlk -> ib_hicon;
  254.                     }
  255.                     else
  256.                     {    /*
  257.                          * haute
  258.                          */
  259.                         pIconBlk -> ib_ytext = ob_height - 10;
  260.                         pIconBlk -> ib_yicon = ob_height - 14 - pIconBlk -> ib_hicon;
  261.                     }
  262.                 #else
  263.                     /*
  264.                      * On peut consid‚rer qu'on est en haute:
  265.                      */
  266.                     pIconBlk -> ib_ytext = ob_height - 10;
  267.                     pIconBlk -> ib_yicon = ob_height - 14 - pIconBlk -> ib_hicon;
  268.                 #endif        
  269.  
  270.                 break;
  271.             
  272.         }
  273.     }
  274.  
  275.     if( !(ob_flags & RELIEF1) && ob_flags & RELIEF2 )
  276.     {    
  277.     
  278.         if( G_nb_colors >= 16 )
  279.         {    /*
  280.              * S'il faut peindre le fond en gris: 
  281.              */
  282.             switch ( ob_type )
  283.             {
  284.                 case    G_BOX:
  285.                 case    G_BOXCHAR:
  286.                     tree[ objc ] .ob_spec.obspec .fillpattern = FORM_PATTERN_16;
  287.                     tree[ objc ] .ob_spec.obspec .interiorcol = FORM_COLOR_16;
  288.                     break;
  289.     
  290.                 case    G_BOXTEXT:
  291.                 case    G_FBOXTEXT:
  292.                 {
  293.                     TE_COLOR        te_color;
  294.                     te_color.value = tree[ objc ] .ob_spec.tedinfo -> te_color;
  295.                     te_color.bf .fillpattern = FORM_PATTERN_16;
  296.                     te_color.bf .interiorcol = FORM_COLOR_16;
  297.                     tree[ objc ] .ob_spec.tedinfo -> te_color = te_color.value;
  298.                     break;
  299.                 }
  300.             }
  301.         }
  302.  
  303. #if COLOR_TEST
  304.         else if( G_nb_colors >= 4 )
  305.         {    /*
  306.              * S'il faut peindre le fond en gris: 
  307.              */
  308.             switch ( ob_type )
  309.             {
  310.                 case    G_BOX:
  311.                 case    G_BOXCHAR:
  312.                     tree[ objc ] .ob_spec.obspec .fillpattern = FORM_PATTERN_4;
  313.                     tree[ objc ] .ob_spec.obspec .interiorcol = FORM_COLOR_4;
  314.                     break;
  315.     
  316.                 case    G_BOXTEXT:
  317.                 case    G_FBOXTEXT:
  318.                 {
  319.                     TE_COLOR        te_color;
  320.                     te_color.value = tree[ objc ] .ob_spec.tedinfo -> te_color;
  321.                     te_color.bf .fillpattern = FORM_PATTERN_4;
  322.                     te_color.bf .interiorcol = FORM_COLOR_4;
  323.                     tree[ objc ] .ob_spec.tedinfo -> te_color = te_color.value;
  324.                     break;
  325.                 }
  326.             }
  327.         }
  328. #endif
  329.  
  330.     }
  331.  
  332.     return    TRUE_1;
  333. }
  334.  
  335.  
  336.  
  337. /*
  338.  * ctrl_icon(-)
  339.  *
  340.  * Purpose:
  341.  * --------
  342.  * Contr“le si un point de l'‚cran appartient … une ic“ne(1) ou non(0)
  343.  *
  344.  * History:
  345.  * --------
  346.  * fplanque: Created
  347.  */
  348. int    ctrl_icon( OBJECT *tree, int    object, int    check_x, int check_y )
  349. {
  350.     int    icon_x, icon_y;
  351.  
  352.     /* Adresse de l'objet-ic“ne: */
  353.     OBJECT    *obj_adr = &( tree[object] );
  354.  
  355.     /* Adresse des infos sur l'ic“ne: */
  356.     ICONBLK *iconblk_adr = obj_adr -> ob_spec. iconblk;
  357.  
  358.     /* Coordonn‚es de l'objet-ic“ne: */
  359.     objc_offset( tree, object, &icon_x, &icon_y );
  360.  
  361.     /*
  362.      * Contr“le:
  363.      * Ce contr“le considŠre que le texte se situe imm‚diatement
  364.      *    AU DESSOUS de l'image de l'ic“ne! 
  365.      */
  366.     if ( check_y >= icon_y + (iconblk_adr -> ib_yicon) )
  367.     {    /* Au dessous du haut de l'image: */
  368.         if (    check_y >= icon_y + (iconblk_adr -> ib_ytext) )    
  369.         { /* Au dessous du haut du texte: */
  370.             if ( check_y < icon_y + (iconblk_adr -> ib_ytext) + (iconblk_adr -> ib_htext) )
  371.             {    /* Dans le texte: */
  372.                 if (    check_x >= icon_x + (iconblk_adr -> ib_xtext)
  373.                     &&    check_x <  icon_x + (iconblk_adr -> ib_xtext) + (iconblk_adr -> ib_wtext) )
  374.                     return    1;
  375.             }
  376.         }
  377.         else
  378.         {    /* Dans l'image: */
  379.             if (    check_x >= icon_x + (iconblk_adr -> ib_xicon)
  380.                 &&    check_x <  icon_x + (iconblk_adr -> ib_xicon) + (iconblk_adr -> ib_wicon) )
  381.                 return    1;
  382.         }
  383.     }
  384.     return    0;
  385. }
  386.  
  387.  
  388.  
  389. /*
  390.  * deselect_current(-)
  391.  *
  392.  * Purpose:
  393.  * --------
  394.  * D‚selectionne l'ic“ne du bureau 
  395.  * ou d'une fenˆtre actuellement s‚lectionn‚e
  396.  *
  397.  * History:
  398.  * --------
  399.  * fplanque: Created
  400.  */
  401. void    deselect_current( void )
  402. {
  403.     if ( G_selection_adr != NULL )
  404.     {    /*
  405.          * S'il y a une ic“ne s‚lectionn‚e: 
  406.          */
  407.         OBJECT    *tree = G_selection_adr -> draw_ptr.tree;
  408.         int        selected_object = G_selection_adr -> selected_icon;
  409.         int        start_obj;
  410.         /*
  411.          * Teste … partir de o— il faut r‚afficher: 
  412.          */
  413.         if (    G_cnf_cope_with_ltf == TRUE_1         /* Si on veut contourner les bugs de let'm fly */
  414.             || tree[selected_object] .ob_type == G_IMAGE )  /* S'il s'agit d'une IMAGE */
  415.         {    /*
  416.              * S'il faut r‚afficher l'objet en dessous 
  417.              * de celui qui nous int‚resse: 
  418.              */
  419.             start_obj = objc_parent( tree, selected_object );    /* On va aussi redessiner le parent sous l'icone */
  420.         }
  421.         else
  422.         {
  423.             start_obj = selected_object;    /* On ne red‚ssine que l'ic“ne elle mˆme */
  424.         }
  425.         /*
  426.          * R‚affiche: 
  427.          */
  428.         modif_icon( G_selection_adr, start_obj, selected_object, NORMAL, TAKE_CTRL );
  429.  
  430.         /*
  431.          * Signale qu'il n'y a plus rien de s‚lectionn‚: 
  432.          */
  433.         no_selection();
  434.     }
  435. }
  436.  
  437.  
  438.  
  439. /*
  440.  * modif_icon(-)
  441.  *
  442.  * Purpose:
  443.  * --------
  444.  * Modifie l'‚tat s‚lectionn‚/d‚selectionn‚ d'une ic“ne du bureau ou d'une fenˆtre
  445.  *
  446.  * History:
  447.  * --------
  448.  * fplanque: Created
  449.  */
  450. void modif_icon( 
  451.         WIPARAMS * params_adr, 
  452.         int start_ob, 
  453.         int icon, 
  454.         int selected, 
  455.         int take_control )
  456. {
  457.     OBJECT    * tree_adr = params_adr -> draw_ptr .tree;  /* Pointeur sur arbe d'objets */
  458.  
  459.     /*
  460.      * Modifie l'‚tat de l'objet: 
  461.      */
  462.     if ( selected )
  463.     {
  464.         tree_adr[icon].ob_state |= SELECTED;    /* S‚lectionne l'ic“ne */
  465.     }
  466.     else
  467.     {
  468.         tree_adr[icon].ob_state &= ~SELECTED ;    /* D‚s‚lectionne l'ic“ne */
  469.     }
  470.  
  471.     /*
  472.      * Teste si on a affaire … un formulaire partag‚: 
  473.      */
  474.     if ( params_adr -> type == TYP_TREE )
  475.     {    /* Si positionnement n‚cessaire: */
  476.         fixform_window( params_adr );        /* Fixe nlle position formulaire */
  477.     }
  478.  
  479.  
  480.     /*
  481.      * R‚affiche l'ic“ne: 
  482.      */
  483.     redraw_icon( params_adr, start_ob, icon, take_control );
  484.         
  485. }
  486.  
  487.  
  488.  
  489. /*
  490.  * redraw_icon(-)
  491.  *
  492.  * Purpose:
  493.  * --------
  494.  * R‚affiche une ic“ne du bureau ou d'une fenˆtre
  495.  *
  496.  * History:
  497.  * --------
  498.  * 1993: fplanque: Created
  499.  */
  500. void    redraw_icon( 
  501.             WIPARAMS *    params_adr, 
  502.             int             start_ob, 
  503.             int             icon, 
  504.             int             take_control )
  505. {
  506.     GRECT        obj_box;                    /* Coordonn‚es de l'objet */
  507.     int        xr, yr, wr, hr;
  508.     OBJECT    * tree_adr = params_adr -> draw_ptr .tree;  /* Pointeur sur arbe d'objets */
  509.     int        handle =    params_adr -> handle;        /* Handle de la "fenˆtre" au sens global */
  510.  
  511.     /*
  512.      * D‚termine les coordonn‚es de l'objet: 
  513.      */
  514.     objc_xywh( tree_adr, icon, &obj_box );
  515.  
  516.     /*
  517.      * On va r‚afficher l'ic“ne, cependant, comme elle peut ˆtre
  518.      * recouverte par une (autre) fenˆtre, on doit proc‚der par un redraw
  519.      * de la fenˆtre … modifier, on cherche donc les intersections de cette
  520.      * fenˆtre visible avec l'ic“ne … modifier... 
  521.      */
  522.  
  523.     /*
  524.      * Auparavant, on s'assure que la liste des rectangles ne va pas bouger 
  525.      */
  526.     if( take_control == TAKE_CTRL )
  527.     {    /*
  528.           * Si l'application n'a pas encore pris le contr“le de l'‚cran 
  529.          * ... on le fait maintenant: 
  530.          */
  531.         start_WINDRAW( NULL );
  532.     }
  533.  
  534.     /* printf("Arbre=%lu start=%d\n", tree_adr, start_ob ); */
  535.  
  536.     /*
  537.      * Parcourt les rectangles de la fenˆtre concern‚e: 
  538.      */
  539.     wind_get( handle, WF_FIRSTXYWH, &xr, &yr, &wr, &hr ); /* Premier rectangle */
  540.     while ( wr && hr )                    /* Tant que dimensions non nulles */
  541.     {
  542.         if ( rcintersect ( G_x_mini, G_y_mini, G_w_maxi, G_h_maxi, &xr, &yr, &wr, &hr ) )
  543.         {    /* Si rectangle est dans l'‚cran */
  544.             if ( rcintersect( obj_box .g_x, obj_box .g_y, obj_box .g_w, obj_box .g_h, &xr, &yr, &wr, &hr ) )
  545.             {    /* Si rect est dans la zone de redraw */
  546.                 objc_draw( tree_adr, start_ob, 4, xr, yr, wr, hr ); /* Affiche ic“ne */
  547.             }
  548.         }
  549.         wind_get( handle, WF_NEXTXYWH, &xr, &yr, &wr, &hr ); /* Rectangle suivant */
  550.     }
  551.  
  552.     /*
  553.      * Peut-ˆtre faut il signaler la fin de la construction de l'‚cran: 
  554.      */
  555.     if( take_control == TAKE_CTRL )
  556.     {    /* Si l'application a pris le contr“le de l'‚cran juste pour redessiner l'ic“ne */
  557.         /* ... on le rends maintenant: */
  558.         end_WINDRAW();
  559.     }
  560.  
  561. }
  562.  
  563.  
  564.  
  565.  
  566. /*
  567.  * sensitive_desk(-)
  568.  *
  569.  * Purpose:
  570.  * --------
  571.  * Hot-Spot des ic“nes du bureau lors d'un drag_[arbo]icon
  572.  *
  573.  * History:
  574.  * --------
  575.  * fplanque: Created
  576.  */
  577. void    sensitive_desk( 
  578.             int new_x, 
  579.             int new_y, 
  580.             int start_obj, 
  581.             int *actual_spot )
  582. {
  583.     /*
  584.      * Variables locales: 
  585.      */
  586.     OBJECT    *tree_adr = G_desktop_adr;    /* Arbre sur lequel on opŠre */
  587.                                                     /* Ds cette version: tjs le bureau */
  588.     int    last_spot = *actual_spot;        /* Dernier objet hot-spot */
  589.     int    new_object;        /* Objet sur lequel se trouve actuelmnt la souris */
  590.  
  591.     /* Determine quel est l'objet sous le csr souris: */
  592.     new_object= objc_find( tree_adr, 0, 1, new_x, new_y );
  593.     /* Au cas on on serait hors du bureau: i.e. dans la barre de menu! */
  594.     if( new_object == NIL )
  595.     {    /* Si on est hors arbre d'objets: */
  596.         new_object = ROOT;    /* On fait comme si on ‚tait sur le fond du bureau... */        
  597.     }
  598.  
  599.     /* Cas d'une ic“ne: v‚rifie qu'on est sur l'image ou le texte... */
  600.     if ( tree_adr[ new_object ] .ob_type == G_ICON )
  601.     {
  602.         if ( !ctrl_icon( tree_adr, new_object, new_x, new_y ) )
  603.         {    /* Si on a seulement cliqu‚ PRES d'une ic“ne: */
  604.             new_object = 0;    /* ATTENTION: Valable uniquement pour desktop */
  605.          }
  606.     }
  607.  
  608.     /* Teste si on a fait un d‚placement significatif */
  609.     if ( new_object != last_spot )
  610.     {    /* Si on a chang‚ d'objet: */
  611.         if ( last_spot != -1 )
  612.         {    /* S'il y avait un objet s‚lectionn‚: */
  613.                 modif_icon( G_desk_params_adr, last_spot, last_spot, NORMAL, CTRL_OK );    /* D‚S‚lectionne l'ancienne ic“ne */
  614.                 *actual_spot = -1;                        /* Plus d'ic“ne s‚lectionn‚e */
  615.         }
  616.         if ( new_object != start_obj )
  617.         {    /* Si on est pas sur l'ic“ne de d‚part */
  618.             if ( tree_adr[ new_object ] .ob_flags & SELECTED )
  619.             {    /* Si on arrive sur un objet pouvant ˆtre s‚lectionn‚ */
  620.                 modif_icon( G_desk_params_adr, new_object, new_object, SELECTED, CTRL_OK );    /* S‚lectionne la nouvelle ic“ne */
  621.                 *actual_spot = new_object;        /* Nlle ic“ne s‚lectionn‚e */
  622.             }
  623.         }
  624.     }
  625. }
  626.  
  627. /*
  628.  * ------------------------ MAPTREE -------------------------
  629.  */
  630.  
  631.  
  632. /*
  633.  * maptree(-)
  634.  *
  635.  * Purpose:
  636.  * --------
  637.  * MapTree
  638.  *
  639.  * Algorythm:
  640.  * ----------  
  641.  * Cette routine va traverser l'arbre
  642.  * depuis l'objet THIS jusqu'au LAST
  643.  *
  644.  * History:
  645.  * --------
  646.  * 1993: fplanque: Created based on Pro-GEM
  647.  */
  648. void    maptree( 
  649.             OBJECT *    tree,                                                 /* In: arbre … parcourir */
  650.             int         this,                                                     /* In: Premier obj … visiter */
  651.             int         last,                                                 /* In: dernier obj a visiter */
  652.             int         (*routine)( OBJECT *tree, int tmp1 ) )        /* In: Fnct … appeller pour chaque objet */
  653. {
  654.  
  655.     int    tmp1 = this;        /* Dernier parent visit‚ */
  656.     
  657.     while( this != last && this != -1 )
  658.     {
  659.         if ( tree[ this ] .ob_tail != tmp1 )
  660.         {
  661.             tmp1 = this;
  662.             this = -1;
  663.             if( (*routine)( tree, tmp1 ) )
  664.             {    /*
  665.                   * Si routine … r‚pondu TRUE
  666.                   */
  667.                 this = tree[ tmp1 ] .ob_head;
  668.             }
  669.             if ( this == -1 )
  670.             {
  671.                 this = tree[ tmp1 ] .ob_next;
  672.             }
  673.         }
  674.         else
  675.         {
  676.             tmp1 = this;
  677.             this = tree[ tmp1 ] .ob_next;
  678.         }
  679.     }
  680. }
  681.  
  682.  
  683.  
  684. /*
  685.  * objc_sel(-)
  686.  * objc_dsel(-)
  687.  * objc_toggle(-)
  688.  * objc_clrsel(-)
  689.  * objc_setsel(-)
  690.  * objc_fixsel(-)
  691.  *
  692.  * Purpose:
  693.  * --------
  694.  * S‚lection d‚selection d'un objet
  695.  *
  696.  * History:
  697.  * --------
  698.  * fplanque: Created
  699.  * 10.05.94: fplanque: Added objc_fixsel()
  700.  */
  701. void    objc_sel( OBJECT *tree, int obj )
  702. {
  703.     if    ( !(tree[ obj ] .ob_state & SELECTED) )
  704.         objc_toggle( tree, obj );
  705. }
  706. void    objc_dsel( OBJECT *tree, int obj )
  707. {
  708.     if    ( tree[ obj ] .ob_state & SELECTED )
  709.         objc_toggle( tree, obj );
  710. }
  711. void    objc_toggle( OBJECT *tree, int obj )
  712. {
  713.     int    state, newstate;
  714.     GRECT    root;
  715.     
  716.     objc_xywh( tree, 0, &root );
  717.     state        = tree[ obj ] .ob_state;
  718.     newstate    = state ^ SELECTED;
  719.     objc_change( tree, obj, 0, root .g_x, root .g_y, root .g_w, root .g_h, newstate, 1 );
  720. }
  721. void    objc_clrsel(  OBJECT *tree, int obj )
  722. {
  723.     tree[ obj ] .ob_state &= ~SELECTED;
  724. }
  725. void    objc_setsel(  OBJECT *tree, int obj )
  726. {
  727.     tree[ obj ] .ob_state |= SELECTED;
  728. }
  729. void    objc_fixsel( 
  730.             OBJECT*    pObj_tree,     /* In: Arbre dans lequel on agit */
  731.             int         n_obj,        /* In: Objet sur lequel on agit */
  732.             int        n_state )   /* In: 0=d‚selection, autre selectionne */
  733. {
  734.     if( n_state )
  735.     {    /* S‚lection: */
  736.         pObj_tree[ n_obj ] .ob_state |= SELECTED;
  737.     }
  738.     else
  739.     {    /* D‚s‚lection: */
  740.         pObj_tree[ n_obj ] .ob_state &= ~SELECTED;
  741.     }
  742. }
  743.  
  744.  
  745.  
  746. /*
  747.  * objc_testsel(-)
  748.  *
  749.  * Purpose:
  750.  * --------
  751.  * Teste si un objet est s‚lectionn‚
  752.  *
  753.  * History:
  754.  * --------
  755.  * 10.05.94: fplanque: Created
  756.  * 24.09.94: retourne BOOL
  757.  */
  758. BOOL    objc_testsel(                 /* Out: !=0 si s‚lectionn‚ */
  759.             OBJECT *    pObj_tree,     /* In: Arbre dans lequel on teste */
  760.             int         n_obj )        /* In: Objet sur lequel on teste */
  761. {
  762.     return ( (pObj_tree[ n_obj ] .ob_state & SELECTED) ? TRUE_1 : FALSE0 );
  763. }
  764.  
  765.  
  766.          
  767.  
  768. /*
  769.  * objc_enable(-)
  770.  * objc_disable(-)
  771.  * objc_setenable(-) 
  772.  * objc_setdisable(-)
  773.  * objc_fixable(-)
  774.  *
  775.  * Purpose:
  776.  * --------
  777.  * Enable-Disable d'un objet
  778.  *
  779.  * History:
  780.  * --------
  781.  * fplanque: Created
  782.  */
  783. void    objc_enable( OBJECT *tree, int obj )
  784. {
  785.     int    state = tree[ obj ] .ob_state;
  786.  
  787.     if ( state & DISABLED )
  788.     {    /* Slt si l'objet est DISABLED: */
  789.         GRECT    root;
  790.  
  791.         objc_xywh( tree, ROOT, &root );
  792.         objc_change( tree, obj, 0,
  793.                          root .g_x, root .g_y, root .g_w, root .g_h,
  794.                          (state ^ DISABLED), 1 );
  795.     }
  796.  
  797. };
  798. void    objc_disable( OBJECT *tree, int obj )
  799. {
  800.     int    state = tree[ obj ] .ob_state;
  801.  
  802.     if ( !(state & DISABLED) )
  803.     {    /* Slt si l'objet n'est *PAS* DISABLED: */
  804.         GRECT    root;
  805.  
  806.         objc_xywh( tree, ROOT, &root );
  807.         objc_change( tree, obj, 0,
  808.                          root .g_x, root .g_y, root .g_w, root .g_h,
  809.                          (state | DISABLED), 1 );
  810.     }
  811. }
  812. void    objc_setenable( OBJECT *tree, int obj )
  813. {
  814.     tree[ obj ] .ob_state &= ~DISABLED;
  815. }
  816. void    objc_setdisable( OBJECT *tree, int obj )
  817. {
  818.     tree[ obj ] .ob_state |= DISABLED;
  819. }
  820. void    objc_fixable( OBJECT *tree, int obj, int enable )
  821. {
  822.     if ( enable )
  823.         tree[ obj ] .ob_state &= ~DISABLED;
  824.     else
  825.         tree[ obj ] .ob_state |= DISABLED;    
  826.  
  827. }
  828.  
  829.  
  830. /*
  831.  * objc_TestEnable(-)
  832.  *
  833.  * Purpose:
  834.  * --------
  835.  * Teste si un objet est s‚lectionn‚
  836.  *
  837.  * History:
  838.  * --------
  839.  * 22.11.94: fplanque: Created
  840.  */
  841. BOOL    objc_TestEnable(             /* Out: !=0 si s‚lectionn‚ */
  842.             OBJECT *    pObj_tree,     /* In: Arbre dans lequel on teste */
  843.             int         n_obj )        /* In: Objet sur lequel on teste */
  844. {
  845.     return ( (pObj_tree[ n_obj ] .ob_state & DISABLED) ? FALSE0 : TRUE_1 );
  846. }
  847.  
  848.  
  849.  
  850. /*
  851.  * ------------------- ENABLE/DISABLE MENU -------------------
  852.  */
  853.  
  854.  
  855. /*
  856.  * enable_menu(-)
  857.  * enable_menuitem(-)
  858.  *
  859.  * Purpose:
  860.  * --------
  861.  * Enable_disable d'un ‚l‚ment menu
  862.  *
  863.  * History:
  864.  * --------
  865.  * 1993: fplanque: Created
  866.  */
  867. void    enable_menu( OBJECT *menu_adr, int enable )
  868. {
  869.     M_enable_menu = enable;
  870.  
  871.     maptree( menu_adr, ROOT, NIL, enable_menuitem );
  872.  
  873. }
  874. int    enable_menuitem( OBJECT *tree, int objc )
  875. {
  876.     if( tree[ objc ] .ob_flags & MENU_DIS )
  877.     {    /* Si l'objet est concern‚: */
  878.         /*    printf("%s\n", tree[ objc ] .ob_spec.free_string ); */
  879.  
  880.         if ( tree[ objc ] .ob_type == G_TITLE )
  881.         {    /* Si c'est un titre: */
  882.             if ( M_enable_menu )
  883.                 objc_enable( tree, objc );
  884.             else
  885.                 objc_disable( tree, objc );
  886.         }
  887.         else
  888.         {    /* Si c'est un ‚l‚ment: */
  889.             menu_ienable( tree, objc, M_enable_menu? 1:0 );
  890.         }
  891.     }
  892.     
  893.     return    TRUE_1;
  894. }
  895.  
  896.  
  897.  
  898. /*
  899.  * ------------------------ - -------------------------
  900.  */
  901.  
  902.  
  903.  
  904. /*
  905.  * open_dialog(-)
  906.  *
  907.  * Purpose:
  908.  * --------
  909.  * Ouvre une boite de dialogue
  910.  *
  911.  * History:
  912.  * --------
  913.  * 1993: fplanque: Created
  914.  */
  915. void    open_dialog( OBJECT *dialog, const GRECT *little_box, GRECT *big_box )
  916. {
  917.     form_center( dialog, &big_box -> g_x, &big_box -> g_y, &big_box -> g_w, &big_box -> g_h );
  918.  
  919.     if ( M_form_recurse_depth == 0 )
  920.     {    /*
  921.          * S'il n'y a pas encore de formulaire ouvert: 
  922.          * On d‚clare cette ouverture … l'AES: 
  923.          */
  924.         form_dial( FMD_START, 0, 0, 0, 0,
  925.             big_box -> g_x, big_box -> g_y, big_box -> g_w, big_box -> g_h );
  926.         /*printf("\033Y  F"); */
  927.     }
  928.     
  929.     form_dial( FMD_GROW, little_box -> g_x, little_box -> g_y, little_box -> g_w, little_box -> g_h,
  930.         big_box -> g_x, big_box -> g_y, big_box -> g_w, big_box -> g_h );
  931.     objc_draw( dialog, 0, 5, big_box -> g_x, big_box -> g_y, big_box -> g_w, big_box -> g_h );
  932.     graf_mouse( ARROW, 0);    /* souris: FlŠche */
  933.  
  934.     /*
  935.      * On a ouvert un formulaire de plus par dessus le pr‚c‚dent 
  936.      */
  937.     M_form_recurse_depth ++;    
  938. }
  939.  
  940.  
  941. /*
  942.  * open_panel(-)
  943.  *
  944.  * Purpose:
  945.  * --------
  946.  * Ouvre une boite de "contr“le" 
  947.  * dont on pourra restorer le fond par raster
  948.  *
  949.  * History:
  950.  * --------
  951.  * fplanque: Created
  952.  */
  953. void    open_panel( 
  954.             OBJECT *dialog, 
  955.             const GRECT *little_box, 
  956.             GRECT *big_box, 
  957.             int center )
  958. {
  959.  
  960. #define    open_panel_debug    0
  961.  
  962.     unsigned    int    nb_lignes;                /* Nbre de lignes … sauver */
  963.     unsigned int    buf_line_nbpixels;    /* Nbre de pixels/ligne ds buffer de sauvegarde (multiple de 16) */
  964.     unsigned    int    buf_line_size;            /* Taille en octets d'une ligne du buffer de sauvegarde */
  965.     unsigned    int    buf_capacity;            /* Capacit‚ de stockage du buffer en lignes de la taille sp‚cif ci-dessus */
  966.  
  967.     #if ( open_panel_debug )
  968.     printf("\x1BY\x20\x20 Debug actif:\n");
  969.     #endif
  970.  
  971.     /* Coordonn‚es formulaire: */
  972.     if ( center == TRUE_1 )
  973.     {    /* Centrage formulaire: */    
  974.         form_center( dialog, &big_box -> g_x, &big_box -> g_y, &big_box -> g_w, &big_box -> g_h );
  975.         /* Correction pour ombrage: */
  976.         if ( dialog[ 0 ] .ob_state & SHADOWED )
  977.         {    /* S'il y a de l'ombre: Compensation: */
  978.             big_box -> g_x --;
  979.             big_box -> g_y --;
  980.             big_box -> g_w += 2;
  981.             big_box -> g_h += 2;
  982.         }
  983.     }
  984.     else
  985.     {    /* Pas de centrage: */
  986.         /* Calcule coordonn‚es du formulaire: */
  987.         objc_xywh( dialog, 0, big_box );
  988.         /* Correction pour ombrage: */
  989.         if ( dialog[ 0 ] .ob_state & SHADOWED )
  990.         {    /* S'il y a de l'ombre: Compensation: */
  991.             big_box -> g_x --;
  992.             big_box -> g_y --;
  993.             big_box -> g_w += 4;
  994.             big_box -> g_h += 4;
  995.         }
  996.     }
  997.  
  998.     #if ( open_panel_debug )
  999.     printf("Zone ‚cran occup‚e: x=%d y=%d w=%d h=%d\n", big_box -> g_x, big_box -> g_y, big_box -> g_w, big_box -> g_h );
  1000.     #endif
  1001.  
  1002.     /* R‚servation d'une zone … l'‚cran? */
  1003.     if ( M_form_recurse_depth == 0 )
  1004.     {    /* S'il n'y a pas encore de formulaire ouvert: */
  1005.         /* On d‚clare cette ouverture … l'AES: */
  1006.         form_dial( FMD_START, 0, 0, 0, 0,
  1007.             big_box -> g_x, big_box -> g_y, big_box -> g_w, big_box -> g_h );
  1008.         /* printf("\033Y  F"); */
  1009.     }
  1010.  
  1011.     /* Effet graphique d'ouverture: */
  1012.     if( little_box != NULL )
  1013.     {    /* Si on a sp‚cifi‚ des coordon‚es pour little bbox: */
  1014.         /* Dessine rectangle en expansion: */
  1015.         form_dial( FMD_GROW, little_box -> g_x, little_box -> g_y, little_box -> g_w, little_box -> g_h,
  1016.             big_box -> g_x, big_box -> g_y, big_box -> g_w, big_box -> g_h );
  1017.     }
  1018.  
  1019.     /* Nombre de lignes … stocker: */
  1020.     nb_lignes = big_box -> g_h;
  1021.  
  1022.     /* Taille n‚cessaire au stockage d'une ligne: */
  1023.     buf_line_nbpixels = ( ( (big_box -> g_w) + 15) & 0xFFF0 );    /* En pixels */
  1024.     buf_line_size = buf_line_nbpixels * G_nb_bitplanes /8;        /* En octets */
  1025.     #if ( open_panel_debug )
  1026.         printf( "Long d'une ligne= %d   ", buf_line_nbpixels );
  1027.         printf( "taille en octets=%d\n", buf_line_size );
  1028.     #endif
  1029.  
  1030.     /* Capacit‚ du buffer AES en lignes: */
  1031.     buf_capacity = (unsigned) (G_long_tampon / buf_line_size);
  1032.     G_stock_tampon = min( buf_capacity, nb_lignes );
  1033.     #if ( open_panel_debug )
  1034.         printf( "Capacit‚ buffer: %d lignes  ", buf_capacity );
  1035.         printf( "=> On stocke %d lignes\n", G_stock_tampon );
  1036.     #endif
  1037.     
  1038.     /* Fixe les coordonn‚es de la copie dans buff AES */
  1039.     G_pxyarray[0]=big_box -> g_x;            /* Coord source */
  1040.     G_pxyarray[1]=big_box -> g_y;
  1041.     G_pxyarray[2]=G_pxyarray[0]+big_box -> g_w-1;
  1042.     G_pxyarray[3]=G_pxyarray[1]+G_stock_tampon-1;
  1043.     G_pxyarray[4]=0;                            /* Coord destination */
  1044.     G_pxyarray[5]=0;
  1045.     G_pxyarray[6]=big_box -> g_w -1;
  1046.     G_pxyarray[7]=G_stock_tampon -1;
  1047.  
  1048.     /* Fixe les paramŠtres (virtuels) de l'‚cran-tampon AES: */
  1049.     G_tamponMFDB.fd_w = buf_line_nbpixels;        /* Largeur ligne */
  1050.     G_tamponMFDB.fd_h = big_box -> g_h;            /* Hauteur (nb_lignes)  */
  1051.     G_tamponMFDB.fd_wdwidth = buf_line_nbpixels /16;    /* Taille en mots d'un seul plan d'une seule ligne */
  1052.     #if ( open_panel_debug )
  1053.     printf("destMFDB w=%d h=%d wInt=%d Plans=%d\n", G_tamponMFDB.fd_w, G_tamponMFDB.fd_h, G_tamponMFDB.fd_wdwidth, G_tamponMFDB.fd_nplanes );
  1054.     #endif
  1055.  
  1056.     /* Op‚ration de copie: */
  1057.     graf_mouse( M_OFF, NULL );
  1058.     vro_cpyfm( G_ws_handle, S_ONLY, G_pxyarray, &G_plogMFDB, &G_tamponMFDB);
  1059.     graf_mouse( M_ON, NULL );
  1060.  
  1061.     /* Si tout n'est pas encore stock‚: */
  1062.     if ( G_stock_tampon < nb_lignes )
  1063.     {
  1064.         nb_lignes -= G_stock_tampon;        /* Nbre de lignes restantes */
  1065.         #if ( open_panel_debug )
  1066.             printf("Il reste … sauver %d lignes ds buffer supp\n", nb_lignes );
  1067.         #endif
  1068.         G_tampon_supp = MALLOC( nb_lignes * buf_line_size );
  1069.         if (G_tampon_supp == NULL)
  1070.         {    /* Pas assez de m‚moire: */
  1071.             signale("Pas assez de m‚moire interne");
  1072.         }
  1073.         else
  1074.         {    /* On va copier ce qui reste */
  1075.             G_pxyarray[1] += G_stock_tampon;                    /* Y de la suite */
  1076.             G_pxyarray[3]    = G_pxyarray[1]+nb_lignes-1;    /* Y + H */
  1077.             G_pxyarray[7]    = nb_lignes -1;                    /* H */
  1078.             G_tamponMFDB.fd_addr = G_tampon_supp;            /* Adr tampon */
  1079.  
  1080.             /* Op‚ration de copie: */
  1081.             graf_mouse( M_OFF, NULL );
  1082.             vro_cpyfm( G_ws_handle, S_ONLY, G_pxyarray, &G_plogMFDB, &G_tamponMFDB);
  1083.             graf_mouse( M_ON, NULL );
  1084.             
  1085.             G_tamponMFDB.fd_addr = G_tampon_aes;        /* Adr tampon */
  1086.         }
  1087.     }
  1088.  
  1089.     /* Dessine formulaire: */
  1090.     objc_draw( dialog, 0, 5, big_box -> g_x, big_box -> g_y, big_box -> g_w, big_box -> g_h );
  1091.     graf_mouse( ARROW, 0);                    /* souris: FlŠche */
  1092.  
  1093.     /* On a ouvert un formulaire de plus par dessus le pr‚c‚dent */
  1094.     M_form_recurse_depth ++;    
  1095.  
  1096.     #undef    open_panel_debug
  1097. }
  1098.  
  1099.  
  1100.  
  1101. /*
  1102.  * close_dialog(-)
  1103.  *
  1104.  * Purpose:
  1105.  * --------
  1106.  * Ferme une boite de dialogue
  1107.  *
  1108.  * History:
  1109.  * --------
  1110.  * fplanque: Created
  1111.  */
  1112. void    close_dialog(
  1113.             OBJECT *dialog, 
  1114.             int exit_obj, 
  1115.             const GRECT *little_box, 
  1116.             const GRECT *big_box )
  1117. {
  1118.     graf_mouse( BUSYBEE, 0);                /* souris: Abeille */
  1119.     objc_clrsel( dialog, exit_obj );        /* Annule s‚lection du bouton de sortie */
  1120.     form_dial( FMD_SHRINK, little_box -> g_x, little_box -> g_y, little_box -> g_w, little_box -> g_h,
  1121.         big_box -> g_x, big_box -> g_y, big_box -> g_w, big_box -> g_h );
  1122.  
  1123.     if ( M_form_recurse_depth <= 1 )
  1124.     {    /* Si on vient de refermer le dernier formulaire ouvert: */
  1125.         /* On le d‚clare … l'AES: */
  1126.         form_dial( FMD_FINISH, 0, 0, 0, 0,
  1127.             big_box -> g_x, big_box -> g_y, big_box -> g_w, big_box -> g_h );
  1128.         /* printf("\033Y  -"); */
  1129.     }
  1130.     
  1131.     /* On a referm‚ le formulaire du haut... */
  1132.         M_form_recurse_depth --;    
  1133. }
  1134.  
  1135.  
  1136.  
  1137.  
  1138. /*
  1139.  * close_pannel(-)
  1140.  *
  1141.  * Purpose:
  1142.  * --------
  1143.  * Ferme une boite de "contr“le" en restorant le fond par raster
  1144.  *
  1145.  * History:
  1146.  * --------
  1147.  * 1993: fplanque: Created
  1148.  */
  1149. void    close_pannel( OBJECT *dialog, int exit_obj, const GRECT *big_box )
  1150. {
  1151.     graf_mouse( BUSYBEE, 0);                /* souris: Abeille */
  1152.     objc_clrsel( dialog, exit_obj );        /* Annule s‚lection du bouton de sortie */
  1153.  
  1154.     /*
  1155.      * Restaure le fond: 
  1156.      */
  1157.     G_pxyarray[0]=0;                            /* Coord source */
  1158.     G_pxyarray[1]=0;
  1159.     G_pxyarray[2]=big_box -> g_w -1;
  1160.     G_pxyarray[3]=G_stock_tampon -1;
  1161.     G_pxyarray[4]=big_box -> g_x;        /* Coord destination */
  1162.     G_pxyarray[5]=big_box -> g_y;
  1163.     G_pxyarray[6]=G_pxyarray[4]+G_pxyarray[2];
  1164.     G_pxyarray[7]=G_pxyarray[5]+G_pxyarray[3];
  1165.  
  1166.     /*
  1167.      * Op‚ration de copie: 
  1168.      */
  1169.     graf_mouse( M_OFF, NULL );
  1170.     vro_cpyfm( G_ws_handle, S_ONLY, G_pxyarray, &G_tamponMFDB, &G_plogMFDB );
  1171.     graf_mouse( M_ON, NULL );
  1172.  
  1173.     if ( G_stock_tampon < big_box -> g_h )
  1174.     {    /*
  1175.          * S'il reste qque chose … copier 
  1176.          */
  1177.         G_pxyarray[3] =     big_box -> g_h - G_stock_tampon -1;
  1178.         G_pxyarray[5] += G_stock_tampon;
  1179.         G_pxyarray[7] =    G_pxyarray[5]+G_pxyarray[3];
  1180.         G_tamponMFDB.fd_addr = G_tampon_supp;        /* Adr tampon suppl‚mentaire */
  1181.  
  1182.         /*
  1183.          * Op‚ration de copie: 
  1184.          */
  1185.         graf_mouse( M_OFF, NULL );
  1186.         vro_cpyfm( G_ws_handle, S_ONLY, G_pxyarray, &G_tamponMFDB, &G_plogMFDB );
  1187.         graf_mouse( M_ON, NULL );
  1188.         
  1189.         G_tamponMFDB.fd_addr = G_tampon_aes;        /* Adr tampon AES std */
  1190.         FREE( G_tampon_supp );                        /* LibŠre le tampon supp */
  1191.         G_tampon_supp = NULL;
  1192.     }
  1193.  
  1194.     if( M_form_recurse_depth <= 1 )
  1195.     {    /* Si on vient de refermer le dernier formulaire ouvert: */
  1196.         /* On le d‚clare … l'AES: */
  1197.         form_dial( FMD_FINISH, 0, 0, 0, 0,
  1198.             big_box -> g_x, big_box -> g_y, big_box -> g_w, big_box -> g_h );
  1199.         /* printf("\033Y  -"); */
  1200.     }
  1201.     
  1202.     /*
  1203.      * On a referm‚ le formulaire du haut... 
  1204.      */
  1205.     M_form_recurse_depth --;    
  1206. }
  1207.  
  1208.  
  1209.  
  1210. /*
  1211.  * abort_pannel(-)
  1212.  *
  1213.  * Purpose:
  1214.  * --------
  1215.  * Ferme une boite de "contr“le" en restorant le fond par raster
  1216.  * avec en PLUS l'effet graphique de fermeture
  1217.  *
  1218.  * Suggest:
  1219.  * --------
  1220.  * Regrouppement avec close enisag‚ -> test si little_box != NULL
  1221.  *
  1222.  * History:
  1223.  * --------
  1224.  * fplanque: Created
  1225.  */
  1226. void    abort_pannel( OBJECT *dialog, int exit_obj, const GRECT *little_box, const GRECT *big_box )
  1227. {
  1228.     form_dial( FMD_SHRINK, little_box -> g_x, little_box -> g_y, little_box -> g_w, little_box -> g_h,
  1229.         big_box -> g_x, big_box -> g_y, big_box -> g_w, big_box -> g_h );
  1230.     close_pannel( dialog, exit_obj, big_box );
  1231. }
  1232.                
  1233.                
  1234.                
  1235. /*
  1236.  * objc_xywh(-)
  1237.  *
  1238.  * Purpose:
  1239.  * --------
  1240.  * Calcule la position et la taille d'un objet
  1241.  *
  1242.  * Suggest:
  1243.  * --------
  1244.  * Ne pas retourner la frame deja en param!
  1245.  *
  1246.  * History:
  1247.  * --------
  1248.  * fplanque: Created
  1249.  */
  1250. GRECT* objc_xywh ( 
  1251.                 OBJECT *tree, 
  1252.                 int objc, 
  1253.                 GRECT *frame )
  1254. {
  1255.     objc_offset( tree, objc, &(frame->g_x), &(frame->g_y) );
  1256.     frame -> g_w = tree[objc].ob_width;
  1257.     frame -> g_h = tree[objc].ob_height;
  1258.     return    frame;
  1259. }
  1260.             
  1261.             
  1262.  
  1263. /*
  1264.  * objc_parent(-)
  1265.  *
  1266.  * Purpose:
  1267.  * --------
  1268.  * Trouve le pŠre d'un objet
  1269.  *
  1270.  * History:
  1271.  * --------
  1272.  * fplanque: Created
  1273.  */
  1274. int    objc_parent( OBJECT *tree, int obj )
  1275. {
  1276.     int    parent;
  1277.     
  1278.     /* Teste si on a bien indiqu‚ un n d'objet: */
  1279.     if (obj == -1 )
  1280.         return -1;
  1281.     
  1282.     parent = tree[ obj ] .ob_next;    /* 1er parent possible */
  1283.     
  1284.     if ( parent != -1 )
  1285.     {    /* Si on ne pointait pas sur le ROOT! */
  1286.         while ( tree[ parent ] .ob_tail != obj )
  1287.         {    /* Tant que l'objet courant n'est pas le dernier Fils du Parent */
  1288.             /*    pr‚sum‚, c'est qu'on a pas attrap‚ le parent! */
  1289.             obj = parent;                            /* Nouvel objet courant */
  1290.             parent = tree[ obj ] .ob_next;    /* Nouveau parent pr‚sum‚ */
  1291.         }
  1292.     }
  1293.     
  1294.     return    parent;
  1295. }
  1296.  
  1297.  
  1298. /*
  1299.  * dlink_teptext(-)
  1300.  *
  1301.  * Purpose:
  1302.  * --------
  1303.  * Modifie le texte d'un objet xTEXT en changeant le pointeur
  1304.  * Sans contr“le de longueur (direct)
  1305.  *
  1306.  * History:
  1307.  * --------
  1308.  * 1993: fplanque: Created
  1309.  */
  1310. void dlink_teptext( 
  1311.         OBJECT *objc_adr, 
  1312.         const char *texte )
  1313. {
  1314.     TEDINFO    *tedinfo_adr = ( objc_adr -> ob_spec.tedinfo ); /* Pointeur sur structure TEDINFO */
  1315.     tedinfo_adr -> te_ptext = (char *)texte;            /* Pointe sur le nouveau texte */
  1316.     tedinfo_adr -> te_txtlen = (int) strlen( texte );    /* Fixe longueur de ce texte */
  1317. }
  1318.  
  1319.  
  1320.  
  1321. /*
  1322.  * rlink_teptext(-)
  1323.  *
  1324.  * Purpose:
  1325.  * --------
  1326.  * Modifie le texte d'un objet xTEXT en changeant le pointeur
  1327.  * Avec contr“le, donnant la priorit‚ … la fin du texte
  1328.  *
  1329.  * Algorythm:
  1330.  * ----------  
  1331.  * Si texte … linker est NULL, on linke G_empty_string
  1332.  *
  1333.  * History:
  1334.  * --------
  1335.  * 1993: fplanque: Created
  1336.  * 28.03.95: linke chaines NULLes
  1337.  */
  1338. void    rlink_teptext( 
  1339.             OBJECT         *    objc_adr, 
  1340.             const char    *    texte )    /* In: texte … linker */
  1341. {
  1342.     TEDINFO    *    tedinfo_adr;        /* Pointeur sur structure TEDINFO */
  1343.     int            long_dem,            /* Longueur demand‚e */
  1344.                     long_max;            /* Longueur maximum autoris‚e */
  1345.  
  1346.     if( texte == NULL )
  1347.     {
  1348.         texte = G_empty_string;
  1349.     }
  1350.     
  1351.     long_dem = (int) strlen ( texte );        /* Longueur demand‚e avec /0 */
  1352.     long_max = ( objc_adr -> ob_width  ) / G_std_text.cell_w +1 ; /* Long max avec /0 */
  1353.     if (long_dem > (long_max) )                /* Si texte trop long! */
  1354.     {
  1355.         texte += (long_dem - long_max +1);        /* D‚place ptr sur la fin affichable */
  1356.         long_dem = long_max;
  1357.     }
  1358.     tedinfo_adr = ( objc_adr -> ob_spec.tedinfo ); /* Pointe sur TEDINFO */
  1359.     tedinfo_adr -> te_ptext = (char *)texte;    /* Pointe sur le nouveau texte */
  1360.     tedinfo_adr -> te_txtlen = long_dem;    /* Fixe longueur de ce texte */
  1361. }
  1362.  
  1363.  
  1364.  
  1365.  
  1366. /*
  1367.  * fix_ftext(-)
  1368.  *
  1369.  * Purpose:
  1370.  * --------
  1371.  * Copie texte dans un objet editable 
  1372.  * Contr“le de longueur
  1373.  * No Redraw
  1374.  *
  1375.  * History:
  1376.  * --------
  1377.  * 1993: fplanque: Created
  1378.  */
  1379. void    fix_ftext( 
  1380.             OBJECT       *    tree,     /* In: Tree */
  1381.             int                 obj,         /* In: dest object */
  1382.             const char *    ftext )    /* In: Source, can be NULL */
  1383. {
  1384.     int        i = 0;
  1385.     int        long_max     = tree[ obj ] .ob_spec.tedinfo -> te_txtlen -1;
  1386.     char        cur_car;
  1387.     char        *te_ptext = tree[ obj ] .ob_spec.tedinfo -> te_ptext;
  1388.  
  1389.     if ( ftext != NULL )
  1390.     {    /*
  1391.          * S'il y a un texte    d'origine: 
  1392.          * Recopie la chaine ‚ditable: 
  1393.          */
  1394.         while (    cur_car = ftext[ i ],
  1395.                     cur_car != '\0'  &&  i < long_max )
  1396.         {
  1397.             te_ptext[ i ] = cur_car;    /* Fixe un caractŠre */
  1398.             i++;
  1399.         }
  1400.     }
  1401.     
  1402.     /* 
  1403.      * Termine la chaine: 
  1404.      */
  1405.     te_ptext[ i ] = '\0';
  1406.  
  1407. }     
  1408.  
  1409.  
  1410.  
  1411. /*
  1412.  * fix_fmtFtext(-)
  1413.  *
  1414.  * Purpose:
  1415.  * --------
  1416.  * Fixe texte dans un objet editable 
  1417.  * Formatt‚
  1418.  *
  1419.  * History:
  1420.  * --------
  1421.  * 1993: fplanque: Created
  1422.  * 17.12.94: gŠre les ftext NULL
  1423.  */
  1424. void    fix_fmtFtext(                     /* Out: */
  1425.             OBJECT         *    tree,        /* In: Arbre contenant l'objet targett‚ */
  1426.             int                 obj,         /* In: Index de l'objet target */
  1427.             const char    *    ftext )    /* In: Ptr sur texte a ins‚rer ds objet */
  1428. {
  1429.     TEDINFO    *tedinfo = tree[ obj ] .ob_spec.tedinfo;
  1430.     char    *te_ptext    = tedinfo -> te_ptext;
  1431.     char    *te_ptmplt     = tedinfo -> te_ptmplt;
  1432.     char    templ, fcar;
  1433.  
  1434.     while( *te_ptmplt != '_' && *te_ptmplt != '\0' )
  1435.     {
  1436.         te_ptmplt ++;        /* Saute le blabla inutile */
  1437.     }
  1438.     
  1439.     if( *te_ptmplt != '\0' && ftext != NULL )        /* Anti-bug */
  1440.     {    /*
  1441.           * Si on a trouv‚ un d‚but de template: 
  1442.           */
  1443.         while(    fcar    = *ftext,
  1444.                     templ    = *(te_ptmplt++),
  1445.                     fcar != '\0' && templ != '\0' )
  1446.         {
  1447.             if( templ == '_' )
  1448.             {    /*
  1449.                  * Si position ‚ditable: 
  1450.                  */
  1451.                 if ( fcar != '.' && fcar != ':' )
  1452.                 {    /*
  1453.                      * Si le car est int‚grable: 
  1454.                      */
  1455.                     *(te_ptext++) = *(ftext++);    /* Copie car */
  1456.                 }
  1457.                 else
  1458.                 {    /*
  1459.                      * Si le car n'est pas int‚grable: 
  1460.                      */
  1461.                     *(te_ptext++) = ' ';        /* Espace */
  1462.                 }
  1463.             }
  1464.             else if ( templ == fcar )
  1465.             {    /*
  1466.                  * S'il s'agit du caractŠre qu'on attendait: 
  1467.                  */
  1468.                 ftext++;        /* Passe sur position suivante dans chaine source */
  1469.             }
  1470.         }
  1471.     }
  1472.  
  1473.     /*
  1474.      * Rajoute \0 final: 
  1475.      */
  1476.     *te_ptext = '\0';
  1477.  
  1478. }
  1479.  
  1480.  
  1481.  
  1482. /*
  1483.  * extract_fmtFtext(-)
  1484.  *
  1485.  * Purpose:
  1486.  * --------
  1487.  * Extrait le texte d'un objet ‚ditable
  1488.  * formatt‚
  1489.  *
  1490.  * Notes:
  1491.  * ------
  1492.  * contient un malloc()
  1493.  *
  1494.  * History:
  1495.  * --------
  1496.  *     1993: fplanque: Created
  1497.  * 11.07.95: fplanque: realloc oubliat la place pour le \0 final
  1498.  */
  1499. char * extract_fmtFtext(     /* Out: nlle chaine contenant texte extrait */
  1500.             OBJECT *    tree,     /* In:  Arbre contenant l'objet */
  1501.             int        obj )        /* In:  No de l'objet contenant le texte */
  1502. {
  1503.     TEDINFO*    tedinfo = tree[ obj ] .ob_spec.tedinfo;
  1504.     char    *    te_ptext    = tedinfo -> te_ptext;
  1505.     char    *    te_ptmplt     = tedinfo -> te_ptmplt;
  1506.     char    *    ftext        = MALLOC( strlen( te_ptmplt ) +1 );        /* Cr‚e zone de longueur maximale + \0 final */
  1507.     char    *    ftext_ptr    = ftext;
  1508.     char        car;
  1509.  
  1510.     while( *te_ptmplt != '_' && *te_ptmplt != '\0' )
  1511.     {
  1512.         te_ptmplt ++;        /* Saute le blabla inutile */
  1513.     }
  1514.  
  1515.     if ( *te_ptmplt != '\0' )        /* Anti-bug */
  1516.     {    /*
  1517.          * Si on a trouv‚ un d‚but de template: 
  1518.          */
  1519.         while( *te_ptext != '\0' )
  1520.         {
  1521.             car = *(te_ptmplt++);
  1522.             if( car == '_' )
  1523.             {    /*
  1524.                  * Si position ‚ditable: 
  1525.                  */
  1526.                 car = *(te_ptext++);
  1527.                 if ( car != ' ' )
  1528.                 {    /*
  1529.                      * Si le car n'est pas un espace de bourrage: 
  1530.                      */
  1531.                     *(ftext_ptr++) = car;
  1532.                 }
  1533.             }
  1534.             else
  1535.             {    /*
  1536.                  * Si caractŠre de formattage: 
  1537.                  */
  1538.                 *(ftext_ptr++) = car;
  1539.             }
  1540.         }
  1541.     }
  1542.  
  1543.     /*
  1544.      * Rajoute \0 final: 
  1545.      */
  1546.     *ftext_ptr = '\0';
  1547.  
  1548.     /*
  1549.      * Restreint … la longueur n‚cessaire: 
  1550.      * (sans oublier le \0 final)
  1551.      */
  1552.     ftext = REALLOC( ftext, strlen( ftext )+1 );
  1553.  
  1554.     /*
  1555.      * Retourne adr chaine FTEXT: 
  1556.      */
  1557.     return    ftext;
  1558. }
  1559.  
  1560.  
  1561. /*
  1562.  * extract_ftext(-)
  1563.  *
  1564.  * Purpose:
  1565.  * --------
  1566.  * Extrait le texte d'un objet ‚ditable
  1567.  * non-formatt‚
  1568.  *
  1569.  * History:
  1570.  * --------
  1571.  * 24.05.94: fplanque: Created
  1572.  */
  1573. char    *extract_ftext( OBJECT *tree, int obj )
  1574. {
  1575.     return    STRDUP( tree[ obj ] .ob_spec.tedinfo -> te_ptext );
  1576. }
  1577.  
  1578.  
  1579. /*
  1580.  * free_text(-)
  1581.  *
  1582.  * Purpose:
  1583.  * --------
  1584.  * Efface le texte associ‚e … une TEDINFO de la m‚moire
  1585.  *
  1586.  * History:
  1587.  * --------
  1588.  * fplanque: Created
  1589.  */
  1590. void free_text( 
  1591.         OBJECT *objc_adr )
  1592. {
  1593.     FREE( ( objc_adr -> ob_spec.tedinfo ) -> te_ptext );
  1594. }
  1595.  
  1596.  
  1597. /*
  1598.  * formdup(-)
  1599.  *
  1600.  * Purpose:
  1601.  * --------
  1602.  * Duplique un arbre d'objets et ses TEDINFOS
  1603.  *
  1604.  * Notes:
  1605.  * ------
  1606.  * Cette routine se base sur le flag LASTOB
  1607.  *
  1608.  * History:
  1609.  * --------
  1610.  * fplanque: Created
  1611.  */
  1612. OBJECT*    formdup( 
  1613.                 OBJECT *srce_tree )
  1614. {
  1615.     OBJECT    *srce_ptr = srce_tree;    /* Pointeur ds l'arbre source */
  1616.     OBJECT    *dest_tree;                    /* Adr arbre de destination */
  1617.     size_t    tree_size;                    /* Taille de l'arbre en octets */
  1618.     int        nb_objects=1;                /* Nombre d'objets */
  1619.     
  1620.     /* Compte le nombre d'objets: */
  1621.     while( ((srce_ptr++) -> ob_flags & LASTOB) == 0     /* Tant que pas dernier objet */
  1622.             && nb_objects < 100 )        /* (Protection anti-boucle sans fin) */
  1623.     {
  1624.         nb_objects++;                        /* Un objet de plus! */
  1625.     }
  1626.     
  1627.     /* Taille de l'arbre: */
  1628.     /* printf("%d * %lu\n",nb_objects,sizeof( OBJECT )); */
  1629.     tree_size = nb_objects * sizeof( OBJECT );
  1630.  
  1631.     /* Copie les objets: */
  1632.     dest_tree = (OBJECT *) MALLOC( tree_size );
  1633.     memcpy( dest_tree, srce_tree, tree_size );
  1634.         
  1635.     /* Parcourt l'arbre pour duplication des TEDINFOS */
  1636.     maptree( dest_tree, ROOT, NIL, dup_tedinfo );
  1637.     
  1638.     return    dest_tree;
  1639. }
  1640.  
  1641.  
  1642.  
  1643. /*
  1644.  * dup_tedinfo(-)
  1645.  *
  1646.  * Purpose:
  1647.  * --------
  1648.  * Duplication des tedinfos
  1649.  *
  1650.  * History:
  1651.  * --------
  1652.  * fplanque: Created
  1653.  */
  1654. int    dup_tedinfo( 
  1655.             OBJECT *tree, 
  1656.             int objc )
  1657. {
  1658.     /* Teste si il faut dupliquer l'OB_SPEC: */
  1659.     if( tree[ objc ] .ob_state & USES_SPEC )
  1660.     {
  1661.     /* Analyse type: */
  1662.         switch( tree[ objc ] .ob_type )
  1663.         {
  1664.             case    G_TEXT:
  1665.             case    G_BOXTEXT:
  1666.             case    G_FTEXT:
  1667.             case    G_FBOXTEXT:    
  1668.             {
  1669.                 TEDINFO    *new_tedinfo = (TEDINFO *) MALLOC ( sizeof( TEDINFO ) );    /* Cr‚e zone */
  1670.                 memcpy( new_tedinfo, tree[ objc ] .ob_spec.tedinfo, sizeof( TEDINFO ) );    /* Recpie TEDINFO */
  1671.                 tree[ objc ] .ob_spec.tedinfo = new_tedinfo;                    /* Fixe nlle adresse */
  1672.                 break;
  1673.             }
  1674.         }
  1675.     }
  1676.     
  1677.     return TRUE_1;
  1678. }
  1679.  
  1680.  
  1681.  
  1682. /*
  1683.  * free_form(-)
  1684.  *
  1685.  * Purpose:
  1686.  * --------
  1687.  * Efface un arbre d'objets dupliqu‚ et ses TEDINFOS dupliqu‚es
  1688.  *
  1689.  * History:
  1690.  * --------
  1691.  * fplanque: Created
  1692.  */
  1693. void    free_form( OBJECT *tree )
  1694. {
  1695.     /* Parcourt l'arbre pour suppression des TEDINFOS */
  1696.     maptree( tree, ROOT, NIL, supress_tedinfo );
  1697.  
  1698.     /* Supprime le formulaire de la m‚moire: */
  1699.     FREE( tree );
  1700. }
  1701.  
  1702.  
  1703.  
  1704.  
  1705. /*
  1706.  * supress_tedinfo(-)
  1707.  *
  1708.  * Purpose:
  1709.  * --------
  1710.  * Supression des tedinfos
  1711.  *
  1712.  * History:
  1713.  * --------
  1714.  * fplanque: Created
  1715.  */
  1716. int    supress_tedinfo( OBJECT *tree, int objc )
  1717. {
  1718.     /* Teste si on a dupliqu‚ l'OB_SPEC: */
  1719.     if( tree[ objc ] .ob_state & USES_SPEC )
  1720.     {
  1721.         /* Analyse type: */
  1722.         switch( tree[ objc ] .ob_type )
  1723.         {
  1724.             case    G_TEXT:
  1725.             case    G_BOXTEXT:
  1726.             case    G_FTEXT:
  1727.             case    G_FBOXTEXT:    
  1728.                 FREE( tree[ objc ] .ob_spec.tedinfo );    /* LibŠre m‚moire */
  1729.                 break;
  1730.         }
  1731.     }
  1732.  
  1733.     return TRUE_1;
  1734. }
  1735.  
  1736.  
  1737.  
  1738. /*
  1739.  * ------------------------ DIRECTORIES -------------------------
  1740.  */
  1741.  
  1742.  
  1743.  
  1744. /*
  1745.  * dir_optimal(-)
  1746.  *
  1747.  * Purpose:
  1748.  * --------
  1749.  * Calcule taille optimale d'une fenêtre directory
  1750.  *
  1751.  * History:
  1752.  * --------
  1753.  * fplanque: Created
  1754.  */
  1755. void    dir_optimal( 
  1756.             int *x_full, 
  1757.             int *y_full, 
  1758.             int *w_full, 
  1759.             int *h_full)
  1760. {
  1761.     *x_full = G_x_mini;
  1762.     *y_full = G_y_mini;
  1763.     *w_full = G_iconw_max_w;
  1764.     *h_full = G_h_maxi;
  1765. }
  1766.  
  1767.  
  1768. /*
  1769.  * open_dir(-)
  1770.  *
  1771.  * Purpose:
  1772.  * --------
  1773.  * Ouvre une fenˆtre directory
  1774.  *
  1775.  * History:
  1776.  * --------
  1777.  * 1993: fplanque: Created
  1778.  * 18.06.94: modif menu_options en fonction de la fenˆtre
  1779.  * 06.08.94: param DATAGROUP remplac‚ par DATADIR
  1780.  */
  1781. void    open_dir( 
  1782.             WIPARAMS *    wi_params_adr, 
  1783.             DATADIR *    pDataDir, 
  1784.             int x_work, 
  1785.             int y_work, 
  1786.             int w_work )
  1787. {
  1788.     int        wi_ckind = wi_params_adr -> wi_ckind;
  1789.  
  1790.     OBJECT    *dir_tree,                    /* Nouvel arbre pour directory */
  1791.                 *dir_tree_ptr;                /* Pointeur dans cet arbre */
  1792.     ICONBLK    *iblk_array,                /* Zone d'iconblks */
  1793.                 *iblk_array_ptr;            /* Pointeur dans cette zone */
  1794.     int        i;                                /* Divers usages */
  1795.     int        curr_x=0, curr_y=0;        /* Position des ic“nes qu'on ajoute */
  1796.     int        max_x;                        /* Largeur de la fenˆtre */
  1797.  
  1798.     int            nb_items        = pDataDir -> nb_elts;    /* Nombres d'‚l‚ments */
  1799.     DATAPAGE        *curr_page    = pDataDir -> data_start; /* Ptr sur premiŠre page */ 
  1800.  
  1801.     /*
  1802.      * Cr‚e un arbre d'objets: 
  1803.      */
  1804.     dir_tree = MALLOC( sizeof( OBJECT ) * (nb_items+1) );    /* Cr‚e zone pour arbre d'objets */
  1805.     
  1806.     /* 
  1807.      * Indique imm‚diatement l'adresse ds params fenˆtre 
  1808.      * car on va en avoir besoin trŠs vite.... 
  1809.      */
  1810.     wi_params_adr -> draw_ptr.tree     = dir_tree;        /* Pointeur sur arbre d'objets */
  1811.  
  1812.     /*
  1813.      * Teste si une fenˆtre semblable est d‚j… ouverte: 
  1814.      */
  1815.     if ( pDataDir -> nb_dirs )
  1816.     {    /* 
  1817.         * On va reprendre le contenu d'une fenˆtre similaire:
  1818.          * Etant donn‚ que les wi_params de la nlle fenˆtre ne sont pas
  1819.          *    encore pr‚sentes dans la liste, on peut demander une recherche
  1820.          *    d'une AUTRE fenˆtre pointant sur le mˆme datagroup:
  1821.          */
  1822.         WIPARAMS *modele_adr = find_datawindow2( (unsigned long) pDataDir, G_wi_list_adr );
  1823.             
  1824.         /*
  1825.          * Copie l'arbre directory du modŠle vers la nlle fenˆtre: 
  1826.          */
  1827.         /*    printf("Dupliq.arbre: modele= %lu -> %lu\n", (modele_adr -> draw_ptr).tree, dir_tree ); */
  1828.         memcpy( dir_tree, (modele_adr -> draw_ptr).tree,
  1829.                      sizeof( OBJECT ) * (nb_items+1) );
  1830.  
  1831.         /*
  1832.          * R‚arrange les ic“nes en fnct de la nlle taille:
  1833.          */
  1834.         rearrange_dir( wi_params_adr, wi_params_adr -> curr_w );
  1835.  
  1836.         /* Remarque: on a gard‚ les iconblks de la 1Šre des fenˆtres semblables! */
  1837.     }
  1838.     else
  1839.     {    /*
  1840.           * On va cr‚er le contenu de la fenˆtre: 
  1841.          * Installe la Boite de fond: 
  1842.          */
  1843.         dir_tree_ptr = dir_tree;
  1844.         memcpy( dir_tree_ptr, &M_single_box, sizeof( OBJECT ) );    /* Copie le pŠre (boŒte blanche) */
  1845.                 
  1846.         /*
  1847.          * Icones: 
  1848.          */
  1849.         /* Position X maxi des ic“nes: */
  1850.             max_x = w_work -(w_work % G_icon_w);
  1851.             if ( max_x < G_icon_w )
  1852.                 max_x = G_icon_w;
  1853.     
  1854.         if ( nb_items )        /* S'il y a des ic“nes: */
  1855.         {
  1856.             ICONIMG    * pIconImg;    /* Donn‚e sur l'ic“ne … utiliser */
  1857.  
  1858.             /*
  1859.              * ParamŠtre M_iconblk: 
  1860.              */
  1861.             switch( pDataDir -> pDataGroup -> DataType )
  1862.             {
  1863.                 case    DTYP_PAGES:        /* Pages ‚cran: */
  1864.                     pIconImg = &(G_icon_images .minitel);
  1865.                     break;
  1866.  
  1867.                 case    DTYP_DATAS:        /* Donn‚es: */
  1868.                     pIconImg = &(G_icon_images .datas);
  1869.                     break;
  1870.                 
  1871.                 case    DTYP_TEXTS:        /* Pages ‚cran: */
  1872.                     pIconImg = &(G_icon_images .texte);
  1873.                     break;
  1874.                     
  1875.                 case    DTYP_PICS:        /* Images: */
  1876.                     pIconImg = &(G_icon_images .image);
  1877.                     break;
  1878.                     
  1879.                 default:
  1880.                     ping();
  1881.             }
  1882.             M_iconblk .ib_pmask = pIconImg -> mask;
  1883.             M_iconblk .ib_pdata = pIconImg -> data;
  1884.             M_iconblk .ib_yicon = pIconImg -> icon_y;
  1885.             M_iconblk .ib_hicon = pIconImg -> icon_h;
  1886.             M_iconblk .ib_xchar = pIconImg -> char_x;
  1887.             M_iconblk .ib_ychar = pIconImg -> char_y;
  1888.                 
  1889.             /*
  1890.              * Cr‚e une zone d'ICONBLK: 
  1891.              */
  1892.             iblk_array = MALLOC( sizeof( ICONBLK ) * nb_items );    /* Cr‚e zone pour ICONBLKs */
  1893.             iblk_array_ptr = iblk_array;
  1894.             /*
  1895.              * Sauvegarde cette adresse: 
  1896.              */
  1897.             pDataDir -> iconblks = iblk_array;
  1898.     
  1899.             for( i = 1; i <= nb_items; i++ )
  1900.             {    /*
  1901.                  * Param‚trage ICONBLK: 
  1902.                  * Modifie NOM de l'ic“ne ds M_iconblk 
  1903.                  */
  1904.                 M_iconblk .ib_ptext = curr_page -> nom;    /* Adresse du nom ds struct DATAPAGE */
  1905.     
  1906.                 /* 
  1907.                  * Copie ICONBLK: 
  1908.                  */
  1909.                 memcpy( iblk_array_ptr, &M_iconblk, sizeof( ICONBLK ) );
  1910.                     
  1911.                 /* 
  1912.                  * Param‚trage OBJECT: 
  1913.                  */
  1914.                 /* Lie M_iconblk … l'objet-ic“ne: */
  1915.                     M_icone .ob_spec.iconblk = iblk_array_ptr++;    /* OB_SPEC Pointe sur M_iconblk */
  1916.     
  1917.                 /*
  1918.                  * Modifie coordonn‚es (relatives au pŠre): 
  1919.                  */
  1920.                     if ( curr_x >= max_x )            /* Si on d‚passe la fin de la fenˆtre: */
  1921.                     {                                        
  1922.                         curr_x = 0;                            /* D‚but de la ligne...    */
  1923.                         curr_y += G_icon_h;                    /* ...ligne suivante */
  1924.                     }
  1925.                     M_icone .ob_x = curr_x;                /* Position X */
  1926.                     M_icone .ob_y = curr_y;                /* Position Y */
  1927.                     curr_x += G_icon_w;                        /* X Prochaine ic“ne */
  1928.         
  1929.                 /*
  1930.                  * Ajoute la nouvelle ic“ne dans l'arbre: 
  1931.                  */
  1932.                 memcpy( ++dir_tree_ptr, &M_icone, sizeof( OBJECT ) );
  1933.  
  1934.                 /*
  1935.                  * Change le caractŠre de l'ic“ne en fonction du statut de sauvegarde:
  1936.                  */
  1937.                 update_iconChar( &M_icone, dataPage_getSavState( curr_page ) );
  1938.     
  1939.                 /* 
  1940.                  * Param‚trage TREE: 
  1941.                  */
  1942.                 /* Lie la nouvelle ic“ne … l'arbre: */
  1943.                     objc_add( dir_tree, 0, i );
  1944.             
  1945.                 /*
  1946.                  * Passe … l'‚l‚ment suivant: 
  1947.                  */
  1948.                 curr_page = curr_page -> next;
  1949.             }
  1950.         }
  1951.         else 
  1952.         {    /*
  1953.              * Si pas d'ic“nes: 
  1954.              */
  1955.             pDataDir -> iconblks = NULL;        /* Pas de zone d'ICONBLKs */
  1956.         }
  1957.             
  1958.         /*
  1959.          * Signale le dernier objet de la fenˆtre: 
  1960.          */
  1961.         dir_tree_ptr -> ob_flags |= LASTOB;
  1962.  
  1963.         /*
  1964.          * Fixe taille de la boŒte de fond: 
  1965.          */
  1966.         dir_tree -> ob_width = G_w_maxi;
  1967.         dir_tree -> ob_height = curr_y + G_h_maxi;
  1968.                     
  1969.         /*
  1970.          * Param‚trage de la fenˆtre: 
  1971.          */
  1972.         wi_params_adr -> total_w    = max_x-1;        /* Taille utile occup‚e par les ic“nes */
  1973.         /* printf("Open: %d\n",wi_params_adr -> total_w); */
  1974.         wi_params_adr -> total_h    = curr_y + G_icon_h - 1;    /* Idem */
  1975.         /* Calc taille ext‚rieure limite en dessous de laquelle il faut
  1976.             r‚arranger les ic“nes dans la fenˆtre: */
  1977.             wind_calc( WC_BORDER, wi_ckind, 100, 100, max_x, 100,
  1978.                                  &i, &i, &(wi_params_adr -> more), &i );
  1979.     }
  1980.  
  1981.     /*
  1982.      * Contr“le position de la fen/doc: 
  1983.      */
  1984.     /* printf("seen y=%d, h=%d, total=%d\n",(int)wi_params_adr -> seen_y, (int)wi_params_adr -> seen_h, (int)wi_params_adr -> total_h ); */
  1985.     if ( get_workYBas( wi_params_adr ) > wi_params_adr -> total_h )
  1986.     {    /* Si la fenˆtre d‚passe le bas du nouveau doc */
  1987.         wi_params_adr -> seen_y = 
  1988.             l_max ( 0, wi_params_adr -> total_h - wi_params_adr -> seen_h );
  1989.     }
  1990.  
  1991.     /*
  1992.      * Positionne l'arbre d'objets: 
  1993.      */
  1994.     dir_tree[0].ob_x = x_work;
  1995.     dir_tree[0].ob_y = y_work - (int) wi_params_adr -> seen_y;
  1996.  
  1997.  
  1998.     /*
  1999.      * Param‚trage de la fenˆtre: 
  2000.      */
  2001.     wi_params_adr -> content_ptr.datadir = pDataDir;    /* contenu */
  2002.     wi_params_adr -> h_step = G_icon_w;                    /* Saut par ic“ne */
  2003.     wi_params_adr -> v_step = G_icon_h;                    /* Saut par ic“ne */
  2004.     /*
  2005.      * Options menu: 
  2006.      */
  2007.     switch( pDataDir -> pDataGroup -> DataType )
  2008.     {
  2009.         case    DTYP_DATAS:        /* Donn‚es: */
  2010.             wi_params_adr -> menu_options.newrub = TRUE_1;    /* On peut cr‚er des nouvelles rubriques */
  2011.             break;
  2012.         
  2013.         case    DTYP_TEXTS:        /* textes: */
  2014.             wi_params_adr -> menu_options.newtext = TRUE_1;    /* On peut cr‚er des nouveaux textes */
  2015.             break;
  2016.     }                        
  2017.  
  2018.     /*
  2019.      * 1 fenˆtre semblable de plus: 
  2020.      */
  2021.     pDataDir -> nb_dirs ++;
  2022. }
  2023.  
  2024.  
  2025.  
  2026.  
  2027. /*
  2028.  * rearrange_dir(-)
  2029.  *
  2030.  * Purpose:
  2031.  * --------
  2032.  * R‚-arrange une fenˆtre directory en fnct de sa nlle taille
  2033.  *
  2034.  * History:
  2035.  * --------
  2036.  * 1993: fplanque: Created
  2037.  */
  2038. void rearrange_dir( WIPARAMS *wi_params_adr, int new_w )
  2039. {
  2040.     OBJECT    *dir_tree = (wi_params_adr -> draw_ptr.tree); /* Pointeur sur l'arbre */
  2041.     int        wi_ckind = wi_params_adr -> wi_ckind;
  2042.     int        i;                                /* Divers usages */
  2043.     int        curr_x=0, curr_y=0;        /* Position des ic“nes qu'on place */
  2044.     int        max_x;                        /* Largeur de la fenˆtre */
  2045.  
  2046.     /*
  2047.      * Position X maxi des ic“nes 
  2048.      */
  2049.     wind_calc( WC_WORK, wi_ckind, 100, 100, new_w, 100,
  2050.                      &i, &i, &max_x, &i );
  2051.     max_x = max_x -(max_x % G_icon_w);
  2052.     if ( max_x < G_icon_w )
  2053.         max_x = G_icon_w;
  2054.     
  2055.     /*
  2056.      * Re-positionne chaque ic“ne: 
  2057.      */
  2058.     i = 0;
  2059.     while( (dir_tree[i] .ob_flags & LASTOB) == 0 )
  2060.     {    /*
  2061.          * Tant qu'on est pas arriv‚ … la fin de l'arbre: 
  2062.          */
  2063.         i++;            /* Passe … l'ic“ne suivante */
  2064.     
  2065.         /*
  2066.          * Modifie coordonn‚es (relatives au pŠre): 
  2067.          */
  2068.         if ( curr_x >= max_x )            /* Si on d‚passe la fin de la fenˆtre: */
  2069.         {                                        
  2070.             curr_x = 0;                            /* D‚but de la ligne...    */
  2071.             curr_y += G_icon_h;                    /* ...ligne suivante */
  2072.         }
  2073.         dir_tree[i] .ob_x = curr_x;        /* Position X */
  2074.         dir_tree[i] .ob_y = curr_y;        /* Position Y */
  2075.         curr_x += G_icon_w;                        /* X Prochaine ic“ne */
  2076.     }
  2077.  
  2078.     /*
  2079.      * Fixe nlle hauteur de la boŒte de fond: 
  2080.      */
  2081.     dir_tree -> ob_height = curr_y + G_h_maxi;
  2082.  
  2083.     /*
  2084.      * Param‚trage de la fenˆtre: 
  2085.      */
  2086.     wi_params_adr -> total_w            = max_x-1;        /* Taille utile occup‚e par les ic“nes */
  2087.     /*    printf("Resize: %d\n",wi_params_adr -> total_w);*/
  2088.     wi_params_adr -> total_h            = curr_y + G_icon_h - 1;    /* Idem */
  2089.  
  2090.     /* 
  2091.      * Calc taille ext‚rieure limite en dessous de laquelle il faut
  2092.      * r‚arranger les ic“nes dans la fenˆtre: 
  2093.      */
  2094.     wind_calc( WC_BORDER, wi_ckind, 100, 100, max_x, 100,
  2095.                          &i, &i, &(wi_params_adr -> more), &i );
  2096.  
  2097. }
  2098.  
  2099.  
  2100.  
  2101.  
  2102. /*
  2103.  * remplace_dir(-)
  2104.  *
  2105.  * Purpose:
  2106.  * --------
  2107.  * Remplace un arbre d'objet directory dans les fenˆtres concern‚es
  2108.  *
  2109.  * History:
  2110.  * --------
  2111.  * 1993: fplanque: Created
  2112.  * 09.08.94: le param est maintenant un DATADIR comme il se doit!
  2113.  * 28.08.94: peut remplacer datadir mˆme si aucune fen ouverte dessus
  2114.  */
  2115. void remplace_dir( DATADIR    * datadir )
  2116. {
  2117.     WIPARAMS    *curr_wi_adr;                                /* Adresse des params de la
  2118.                                                                 /* fen en cours de traitement */
  2119.     int        x_work, y_work, w_work, foo;             /* Coord zone de travail */
  2120.     int        wi_ckind;                    /* El‚ments des fen^etres concern‚es */
  2121.  
  2122.     /* 
  2123.      * PremiŠre ‚tape: 
  2124.      * Effacer les anciens arbres d'objets et l'ICONBLK
  2125.      * On recherche la premiŠre fenˆtre concern‚e
  2126.      * d'aprŠs leur datagroup: 
  2127.      */
  2128.     curr_wi_adr = find_datawindow2( (unsigned long) datadir, G_wi_list_adr );
  2129.  
  2130.     while ( curr_wi_adr != NULL )
  2131.     {
  2132.         /*    printf("Adr Fen concern‚e: %lX\n",curr_wi_adr);*/
  2133.  
  2134.         /* Efface le directory de la fenˆtre: */
  2135.         efface_dir( curr_wi_adr );
  2136.  
  2137.         /* Trouve prochaine fenˆtre */
  2138.         curr_wi_adr = find_datawindow2( (unsigned long) datadir, curr_wi_adr -> next ); 
  2139.  
  2140.     }
  2141.  
  2142.     /* 
  2143.      * DeuxiŠme ‚tape: Cr‚er un nouvel arbre d'objets & ICONBLK 
  2144.      *    et le fixer dans les fenˆtres concern‚es: 
  2145.      * PremiŠre fenˆtre … traiter: 
  2146.      */
  2147.     curr_wi_adr = find_datawindow2( (unsigned long) datadir, G_wi_list_adr );
  2148.  
  2149.     while ( curr_wi_adr != NULL )
  2150.     {
  2151.         wi_ckind        = curr_wi_adr -> wi_ckind;        /* El‚ments des fenetres … traiter */
  2152.     
  2153.         /* printf("Adr Fen concern‚e: %lX\n",curr_wi_adr); */
  2154.          /*    printf("Fen no= %d: ",curr_wi_adr -> handle ); */
  2155.  
  2156.         /* Coord zone de travail: */
  2157.         wind_calc( WC_WORK, wi_ckind, curr_wi_adr -> curr_x,
  2158.              curr_wi_adr -> curr_y, curr_wi_adr -> curr_w, 100,
  2159.              &x_work, &y_work, &w_work, &foo );
  2160.  
  2161.         /* Ouvre nouveau directory */
  2162.         open_dir( curr_wi_adr, datadir, x_work, y_work, w_work );
  2163.  
  2164.         /* Modifie ligne d'informations: */
  2165.         set_infoline( curr_wi_adr, dir_infoline );
  2166.  
  2167.         /* Demande redraw total de la fenˆtre: */
  2168.         send_fullredraw( curr_wi_adr );
  2169.  
  2170.         /* Fixe Nouvel ascenseur */
  2171.         set_slider_h( curr_wi_adr );        /* Fixe taille */
  2172.         set_slider_y( curr_wi_adr );        /* Fixe position asc */
  2173.  
  2174.         /* Trouve prochaine fenˆtre */
  2175.         curr_wi_adr = find_datawindow2( (unsigned long) datadir, curr_wi_adr -> next ); 
  2176.  
  2177.     }
  2178. }
  2179.  
  2180.  
  2181.  
  2182. /*
  2183.  * efface_dir(-)
  2184.  *
  2185.  * Purpose:
  2186.  * --------
  2187.  * Efface un arbre d'objet directory dans 1 fenˆtre
  2188.  * et la zone d'ICONBLKS s'il s'agissait de la derniŠre fenˆtre
  2189.  *
  2190.  * History:
  2191.  * --------
  2192.  * 1993: fplanque: Created
  2193.  */
  2194. void    efface_dir( WIPARAMS *wi_params_adr )
  2195. {
  2196.     /* 
  2197.      * Groupe de donn‚e dont on vient de fermer (une)/(la derniŠre) fenˆtre: 
  2198.      * Ou dont on veut remplacer le directory: 
  2199.      */
  2200.     DATAGROUP    *curr_datagr = wi_params_adr -> datagroup;    /* Datagroup concern‚ */
  2201.     DATADIR        *datadir         = curr_datagr -> root_dir;        /* Dossier ppal du Datagroup */
  2202.  
  2203.     /* Une fenˆtre de moins... */
  2204.     /* Teste s'il reste des fenˆtres semblables */
  2205.     if ( --(datadir -> nb_dirs) == 0)
  2206.     {    /* Si on vient de fermer la derniŠre fenˆtre: */
  2207.         if ( datadir -> iconblks != NULL )
  2208.         {    /* S'il y avait des ic“nes et donc une zone d'ICONBLKs
  2209.             /*    ds la derniŠre fenˆtre: */
  2210.             FREE( datadir -> iconblks );     /* Efface tableau d'ICONBLK: */
  2211.         }
  2212.     }
  2213.             
  2214.     /*
  2215.      * Efface arbre d'ic“nes de la m‚moire 
  2216.      */
  2217.     FREE( wi_params_adr -> draw_ptr.tree );
  2218. }
  2219.  
  2220.  
  2221.  
  2222. /*
  2223.  * dir_infoline(-)
  2224.  *
  2225.  * Purpose:
  2226.  * --------
  2227.  * Cr‚e ligne d'informations sur un directory
  2228.  *
  2229.  * History:
  2230.  * --------
  2231.  * fplanque: Created
  2232.  */
  2233. char    *dir_infoline( WIPARAMS *wi_params_adr )
  2234. {
  2235.  
  2236.     int    nb_elts = (wi_params_adr -> datadir) -> nb_elts;
  2237.  
  2238.     /* Cr‚ation de la ligne d'infos: */
  2239.     if( nb_elts )
  2240.     {
  2241.         G_tmp_buffer[ 0 ] = ' ';
  2242.         itoa( nb_elts, &G_tmp_buffer[ 1 ], 10 );    /* Nombre d'‚l‚ments */
  2243.         if ( nb_elts == 1 )
  2244.             strcat( G_tmp_buffer, " ‚l‚ment." );
  2245.         else
  2246.             strcat( G_tmp_buffer, " ‚l‚ments." );
  2247.     }
  2248.     else
  2249.     {    /* Dossier vide */
  2250.         strcpy( G_tmp_buffer, " Aucun ‚l‚ment." );        /* Bug corrig‚ le 6/8/93 */
  2251.     }
  2252.  
  2253.     return    STRDUP( G_tmp_buffer );
  2254. }
  2255.  
  2256.  
  2257.  
  2258. /*
  2259.  * dir_infoline_selection(-)
  2260.  *
  2261.  * Purpose:
  2262.  * --------
  2263.  * Modifie la ligne d'informations sur le dir 
  2264.  * lorsqu'on a s‚lectionn‚ une icone
  2265.  *
  2266.  * History:
  2267.  * --------
  2268.  * 1993: fplanque: Created
  2269.  */
  2270. char    *    dir_infoline_selection( 
  2271.                 WIPARAMS *wi_params_adr )
  2272. {
  2273.     DATADIR    *    datadir            = wi_params_adr -> datadir;
  2274.     int            selected_icon    = wi_params_adr -> selected_icon;
  2275.     char        *    dataname            = ((wi_params_adr -> draw_ptr.tree)[selected_icon] .ob_spec.iconblk) -> ib_ptext;
  2276.     DATAPAGE    *    datapage             = page_adr_byname( datadir, dataname ); 
  2277.     char        *    comment            = datapage -> comment;
  2278.  
  2279.     /*
  2280.      * Cr‚ation de la ligne d'infos: 
  2281.      */
  2282.     strcpy( G_tmp_buffer, " S‚lection: " );
  2283.     strcat( G_tmp_buffer, dataname );        /* Ajoute nom de la page */
  2284.     if ( comment != NULL )
  2285.     {
  2286.         strcat( G_tmp_buffer, " = " );
  2287.         strcat( G_tmp_buffer, comment );        /* Ajoute commentaire */
  2288.     }
  2289.  
  2290.     return    STRDUP( G_tmp_buffer );
  2291. }
  2292.  
  2293.  
  2294.  
  2295.  
  2296. /*
  2297.  * update_iconChar(-)
  2298.  *
  2299.  * Purpose:
  2300.  * --------
  2301.  * Modifie le caractŠre d'une ic“ne de maniŠre … ce qu'elle reflŠte
  2302.  * le statut de sauvegarde de l'objet auquel elle se rapporte
  2303.  *
  2304.  * History:
  2305.  * --------
  2306.  * 06.08.94: fplanque: Created
  2307.  */
  2308. void    update_iconChar( 
  2309.             OBJECT *    pObject,        /* In: Ic“ne … modofier */
  2310.             SSTATE    sstate    )    /* In: Etat de l'objet auquel l'icone se rapporte */        
  2311. {
  2312.     char    newChar;
  2313.     int * pIconChar = &(pObject -> ob_spec.iconblk -> ib_char);    
  2314.  
  2315.     switch( sstate )
  2316.     {
  2317.         case    SSTATE_EMPTY:
  2318.             newChar = CEMPTY;
  2319.             break;
  2320.     
  2321.         case    SSTATE_MODIFIED:
  2322.             newChar = '*';
  2323.             break;
  2324.  
  2325.         case    SSTATE_SAVED:
  2326.             newChar = ' ';
  2327.             break;
  2328.             
  2329.         default:
  2330.             newChar = '?';
  2331.             signale( "Unknown SSTATE" );
  2332.     }
  2333.  
  2334.     *pIconChar = ((*pIconChar) & 0xFF00) | newChar;
  2335. }
  2336.  
  2337.  
  2338.  
  2339. /*
  2340.  * find_iconByNamePtr(-)
  2341.  *
  2342.  * Purpose:
  2343.  * --------
  2344.  * Trouve une ic“ne dans une fenˆtre directory en fonction
  2345.  * du pointeur sur son nom (texte)
  2346.  *
  2347.  * History:
  2348.  * --------
  2349.  * 06.08.94: fplanque: Created
  2350.  * 21.09.94: adapt‚ aux arbres arbo
  2351.  */
  2352. int find_iconByNamePtr(                /* Out: Index ic“ne */
  2353.             OBJECT     *     pObj_Tree,
  2354.             char        *    psz_nom )
  2355. {
  2356.     int i;
  2357.  
  2358.     for( i=0; (pObj_Tree[i] .ob_flags & LASTOB) == 0; )
  2359.     {    /*
  2360.          * Tant qu'on est pas arriv‚ … la fin de l'arbre: 
  2361.          */
  2362.         i++;            /* Passe … l'ic“ne suivante */
  2363.  
  2364.         /*
  2365.          * Compare textes/noms: 
  2366.          */
  2367.         if( ((pObj_Tree[i] .ob_type ) & 0x00FF ) == G_ICON
  2368.             && ((pObj_Tree[i] .ob_spec.iconblk) -> ib_ptext ) == psz_nom )
  2369.         {
  2370.             return    i;
  2371.         }
  2372.     }
  2373.  
  2374.     return    NIL_1;
  2375. }
  2376.  
  2377.  
  2378.  
  2379. /*
  2380.  * find_ObjBySpec(-)
  2381.  *
  2382.  * Purpose:
  2383.  * --------
  2384.  * Trouve un objet dans un arbre en fonction de son ptr sur ob_spec
  2385.  *
  2386.  * History:
  2387.  * --------
  2388.  * 09.10.94: fplanque: Created
  2389.  */
  2390. int find_ObjBySpec(                /* Out: Index objet trouv‚ ou NIL_1 */
  2391.             OBJECT     *     pObj_Tree,
  2392.             void        *    ob_spec )
  2393. {
  2394.     int i;
  2395.  
  2396.     for( i=0; (pObj_Tree[i] .ob_flags & LASTOB) == 0; )
  2397.     {    /*
  2398.          * Tant qu'on est pas arriv‚ … la fin de l'arbre: 
  2399.          */
  2400.         i++;            /* Passe … l'ic“ne suivante */
  2401.  
  2402.         /*
  2403.          * Compare textes/noms: 
  2404.          */
  2405.         if( pObj_Tree[i] .ob_spec.free_string == ob_spec )
  2406.         {
  2407.             return    i;
  2408.         }
  2409.     }
  2410.  
  2411.     return    NIL_1;
  2412. }
  2413.  
  2414.  
  2415.  
  2416. /*
  2417.  * find_ObjByXY(-)
  2418.  *
  2419.  * Purpose:
  2420.  * --------
  2421.  * Trouve un objet dans un arbre
  2422.  * en fonction de ses coordonn‚es
  2423.  *
  2424.  * History:
  2425.  * --------
  2426.  * 06.10.94: fplanque: Created
  2427.  */
  2428. int find_ObjByXY(                        /* Out: Index ic“ne */
  2429.             OBJECT     *     pObj_Tree,
  2430.             int            n_x,
  2431.             int            n_y )
  2432. {
  2433.     int i;
  2434.  
  2435.     for( i=0; (pObj_Tree[i] .ob_flags & LASTOB) == 0; )
  2436.     {    /*
  2437.          * Tant qu'on est pas arriv‚ … la fin de l'arbre: 
  2438.          */
  2439.         i++;            /* Passe … l'obj suivant */
  2440.  
  2441.         /*
  2442.          * Compare coords: 
  2443.          */
  2444.         if( pObj_Tree[i] .ob_x == n_x && pObj_Tree[i] .ob_y == n_y )
  2445.         {
  2446.             return    i;
  2447.         }
  2448.     }
  2449.  
  2450.     return    NIL_1;
  2451. }
  2452.